package com.lemlin.network

import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.LogUtils
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okio.Buffer
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.*
import java.util.concurrent.TimeUnit


object HttpServiceFactory {

    private fun client(isInterceptor: Boolean = true): OkHttpClient.Builder {
        val builder = OkHttpClient.Builder()
        builder.writeTimeout(30.toLong(), TimeUnit.SECONDS)
        builder.readTimeout(30.toLong(), TimeUnit.SECONDS)
        builder.connectTimeout(30.toLong(), TimeUnit.SECONDS)
//        if (isInterceptor)
//            builder.addInterceptor(SigningInterceptor())
        if (AppUtils.isAppDebug())
            builder.addInterceptor(LoggingInterceptor())
        return builder
    }

    fun <ApiService> create(clazz: Class<ApiService>, baseUrl: String): ApiService {
        val retrofit: Retrofit = Retrofit.Builder()
            .client(client().build())
            .baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
        return retrofit.create(clazz)
    }

    fun create(listener: WebSocketListener, wsUrl: String): WebSocket {
        val request: Request = Request.Builder()
            .url(wsUrl)
            .build()
        return client(isInterceptor = false).build().newWebSocket(request, listener)
    }

    /**
     * 拦截添加请求头 并刷新token
     */
    internal class SigningInterceptor : Interceptor {

        override fun intercept(chain: Interceptor.Chain): Response {
            val token: String = "b8c254d5-f19c-4ebd-8fda-5440dc4c7f6c"

            val request: Request = chain.request().newBuilder()
                .build()
            val response: Response = chain.proceed(request)
//            if (response.code == 401) {
//                return chain.proceed(
//                    chain.request().newBuilder()
//                        .addHeader("token", token)
//                        .build()
//                )
//            }
            return chain.proceed(
                chain.request().newBuilder()
                    .addHeader("token", token)
                    .build()
            )
        }
    }

    /**
     * Log拦截
     */
    internal class LoggingInterceptor : Interceptor {

        private val mediaType: MediaType = "application/octet-stream".toMediaTypeOrNull()!!

        override fun intercept(chain: Interceptor.Chain): Response {
            //发送时截取数据
            val request = chain.request()
            val t1 = System.nanoTime()
            val body = request.body
            val buffer = Buffer()
            if (body?.contentType() != mediaType){
                body?.writeTo(buffer)
            }

            val send = String.format(
                Locale.CHINA, ("发送请求:%s%n请求JSON:%s"),
                request.url,
                if (body?.contentType() == mediaType)
                    "This is the file upload" else buffer.readUtf8()
            )
            LogUtils.e(send)

            //接收时截取数据
            val response = chain.proceed(request)
            val t2 = System.nanoTime()
            val responseBody = response.peekBody((1024 * 1024).toLong())

            val accept = String.format(
                Locale.CHINA, ("接收响应:%s%n请求时间:%.1fms%n报文信息:%s返回JSON:%s"),
                response.request.url,
                (t2 - t1) / 1e6,
                response.headers,
                if (responseBody.contentType() == mediaType)
                    "This is the file download" else responseBody.string()
            )
            LogUtils.e(accept)

            return response
        }
    }
}